; CONVERTED TASM PIC16F877 GEPE456.ASM TO MPASM GEPE456_M.ASM 06-10-2003 17:56:05

                list p=PIC16F877A,r=dec
		include P16F877A.inc
		ERRORLEVEL -302
                                       
#DEFINE         PAGE0 BCF H'03',5     ;STATUS bit 5
#DEFINE         PAGE1 BSF H'03',5     ;STATUS bit 5
                 
INDF            EQU H'00'               ;page 0, 1, 2, 3
;OPTION_REG      EQU H'01'               ;page 1, 3
PCL             EQU H'02'               ;page 0, 1, 2, 3
STATUS          EQU H'03'               ;page 0, 1, 2, 3
FSR             EQU H'04'               ;page 0, 1, 2, 3
                 
;PORTA           EQU H'05'               ;page 0
;TRISA           EQU H'05'               ;page 1
;PORTB           EQU H'06'               ;page 0, 2
;TRISB           EQU H'06'               ;page 1, 3
;PORTC           EQU H'07'               ;page 0
;TRISC           EQU H'07'               ;page 1
;PORTD           EQU H'08'               ;page 0
;TRISD           EQU H'08'               ;page 1
;PORTE           EQU H'09'               ;page 0
;TRISE           EQU H'09'               ;page 1
;INTCON          EQU H'0B'               ;page 0, 1, 2, 3
;EEDATA          EQU H'0C'               ;page 2
;EECON1          EQU H'0C'               ;page 3
;EEADR           EQU H'0D'               ;page 2
                 
LOOPB           EQU H'20'               ; general loop
LOOPC           EQU H'21'               ; general loop
LOOPD           EQU H'22'               ; general loop
LOOPE           EQU H'23'               ; general loop
STORE1          EQU H'24'               ; temp store
TEMPA           EQU H'25'               ; temp store
CLKCNT          EQU H'26'               ; counter for PAUSE val
ADRLSB          EQU H'27'               ; low address
ADRMSB          EQU H'28'               ; high address
ATTRIB          EQU H'29'               ; ATTRIBUTE value
BITVAL          EQU H'2A'               ; val of bit to be set/reset
RDBYTE          EQU H'2B'               ; byte read from screen
COUNT           EQU H'2C'               ; counter for BIRD loop, used also for waveform
COLUMN          EQU H'2D'               ; column length holder
QCKCOL          EQU H'2E'               ; quack bill column
PEAKLO          EQU H'2F'               ; waveform peak lo (demo 11)
PEAKHI          EQU H'30'               ; waveform peak hi (demo 11)
LOBIT           EQU H'31'               ; waveform section (demo 11)
LOOPLO          EQU H'32'               ; waveform section (demo 11)
                 
JOIN00          EQU H'34'               ; 1st store for BIRD roll-over join (right-hand edge bit)
                                        ; extends to $50 for JOIN32, used also for waveforms
                                        ; (64 for scope style)
                 
                                        ;........FIXED VALUES FOR COMMANDS
                 
TXHOME          EQU H'40'               ; text home address command
TXAREA          EQU H'41'               ; text area (columns) address command
GRHOME          EQU H'42'               ; graphics home address command
GRAREA          EQU H'43'               ; graphic area (columns) address command
AWRON           EQU H'B0'               ; autowrite on command
AWROFF          EQU H'B2'               ; autowrite off command
OFFSET          EQU H'22'               ; offset command
ADPSET          EQU H'24'               ; address set command
PEEK            EQU H'E0'               ; screen peek command
CSRPOS          EQU H'21'               ; set cursor position ommand
                 
                                        ;........BIT VALUES
                 
W               EQU 0                   ; working reg
F               EQU 1                   ; file reg
Z               EQU 2                   ; zero status
C               EQU 0                   ; CARRY status
RP0             EQU 5                   ; STATUS bank reg
RP1             EQU 6                   ; STATUS bank reg
RD              EQU 0                   ; EEPROM read flag
EEPGD           EQU 7                   ; EECON1 reg
FS              EQU B'00000000'         ;FS mode set by bit 5: 1 = 6x8, 0 = 8x8
                                        ;8x8 needed for EPE demos
                 
                                        ;..........
                 
                ORG H'04'
                goto 5
                ORG H'05'
                 
                bcf STATUS,RP0
                bcf STATUS,RP1
                clrf PORTA
                clrf PORTB
                movlw B'00001111'       ; FS low, RST low, CD CE RD WR high
                movwf PORTC
                clrf PORTD
                clrf PORTE
                PAGE1 
                movlw 255
                movwf TRISA             ; PORTA as input
                clrf TRISB              ; PORTB as output
                movlw FS
                movwf TRISC             ; PORTC as output GRAPHIC LCD control/FS
                clrf TRISD              ; PORTD as output GRAPHIC LCD D0-D7
                clrf TRISE              ; PORTE as output
                movlw B'10000110'       ; pull-up Rs off (bit 7 hi), timer 1/25 sec
                movwf OPTION_REG        ; (for 3.2768MHz xtal)
                PAGE0
                movlw B'00011111'       ; FS low,  RST CD CE RD WR high
                movwf PORTC
                 
                call PAUSIT
                goto GRAPHIC
                 
TABLE1          addwf PCL,F
                retlw 'G'
                retlw 'R'
                retlw 'A'
                retlw 'P'
                retlw 'H'
                retlw 'I'
                retlw 'C'
                retlw ' '
                retlw 'L'
                retlw 'C'
                retlw 'D'
                retlw ' '
                retlw 'D'
                retlw 'E'
                retlw 'M'
                retlw 'O'
                 
                retlw 'E'
                retlw 'P'
                retlw 'E'
                retlw ' '
                retlw 'S'
                retlw 'H'
                retlw 'O'
                retlw 'W'
                retlw 'S'
                retlw ' '
                retlw 'Y'
                retlw 'O'
                retlw 'U'
                retlw ' '
                retlw 'H'
                retlw 'O'
                retlw 'W'
                retlw '!'
                 
                retlw 'T'
                retlw 'H'
                retlw 'I'
                retlw 'S'
                retlw ' '
                retlw 'I'
                retlw 'S'
                retlw ' '
                retlw 'P'
                retlw 'A'
                retlw 'G'
                retlw 'E'
                retlw ' '
                retlw '2'
                 
                retlw 'Q'
                retlw 'U'
                retlw 'A'
                retlw 'C'
                retlw 'K'
                 
AMPLIFIER       addwf PCL,F
                retlw H'80'             ; amp top left + first slope down   (1
                 
                retlw H'83'             ;amp input                          (2
                retlw H'86'             ;cap top
                retlw H'83'             ;amp input
                retlw H'83'             ;amp input
                retlw H'81'             ;amp left
                retlw H'82'             ;amp slope down
                retlw H'83'             ;amp output
                retlw H'86'             ;cap top
                retlw H'83'             ;amp output
                 
                retlw H'8B'             ;word IN                               (3
                retlw H'87'             ;cap bot
                retlw H'89'             ;resistor top
                retlw H'00'
                retlw H'81'             ;amp left
                retlw H'84'             ;amp slope up
                retlw H'00'
                retlw H'87'             ;cap bot
                retlw H'8C'             ;1st part OUT
                retlw H'8D'             ;2nd part OUT
                 
                retlw H'88'             ;resistor                              (4
                retlw H'00'
                retlw H'85'             ;amp bot left + first slope up
                 
                retlw H'88'             ;resistor                              (5
                retlw H'8A'             ;resistor bot                          (6
                retlw H'8E'             ;0V                                    (7
                 
CGTABLE         addwf PCL,F             ; EXTERNAL CG FONT DATA
                 
                retlw B'10000000'       ; CHARACTER $80
                retlw B'11000000'       ; amp top left + first slope down
                retlw B'10100000'
                retlw B'10010000'
                retlw B'10001000'
                retlw B'10000100'
                retlw B'10000010'
                retlw B'10000001'
                 
                retlw B'10000000'       ; CHARACTER $81
                retlw B'10000000'       ; amp left
                retlw B'10000000'
                retlw B'10000000'
                retlw B'10000000'
                retlw B'10000000'
                retlw B'10000000'
                retlw B'10000000'
                 
                retlw B'10000000'       ; CHARACTER $82
                retlw B'01000000'       ; amp slope down
                retlw B'00100000'
                retlw B'00010000'
                retlw B'00001000'
                retlw B'00000100'
                retlw B'00000010'
                retlw B'00000001'
                 
                retlw B'00000000'       ; CHARACTER $83
                retlw B'00000000'       ; amp output
                retlw B'00000000'
                retlw B'00000000'
                retlw B'00000000'
                retlw B'00000000'
                retlw B'00000000'
                retlw B'11111111'
                 
                retlw B'00000001'       ; CHARACTER $84
                retlw B'00000010'       ; amp slope up
                retlw B'00000100'
                retlw B'00001000'
                retlw B'00010000'
                retlw B'00100000'
                retlw B'01000000'
                retlw B'10000000'
                 
                retlw B'10000001'       ; CHARACTER $85
                retlw B'10000010'       ; amp bot left + first slope up
                retlw B'10000100'
                retlw B'10001000'
                retlw B'10010000'
                retlw B'10100000'
                retlw B'11000000'
                retlw B'10000000'
                 
                retlw B'00000000'       ; CHARACTER $86
                retlw B'00000000'       ; capacitor top
                retlw B'01111010'
                retlw B'01001010'
                retlw B'01001010'
                retlw B'01001010'
                retlw B'01001010'
                retlw B'11001011'
                 
                retlw B'01001010'       ; CHARACTER $87
                retlw B'01001010'       ; capacitor bot
                retlw B'01001010'
                retlw B'01001010'
                retlw B'01001010'
                retlw B'01111010'
                retlw B'00000000'
                retlw B'00000000'
                 
                retlw B'00001000'       ; CHARACTER $88
                retlw B'00000100'       ; resistor
                retlw B'00000010'
                retlw B'00000001'
                retlw B'00000010'
                retlw B'00000100'
                retlw B'00001000'
                retlw B'00010000'
                 
                retlw B'00000010'       ; CHARACTER $89
                retlw B'00000010'       ; resistor top
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000100'
                retlw B'00001000'
                retlw B'00010000'
                 
                retlw B'00001000'       ; CHARACTER $8A
                retlw B'00000100'       ; resistor bot
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000010'
                retlw B'00000000'
                 
                retlw B'00000000'       ; CHARACTER $8B
                retlw B'00000000'       ; word IN
                retlw B'10010010'
                retlw B'10011010'
                retlw B'10010110'
                retlw B'10010010'
                retlw B'00000000'
                retlw B'00000000'
                 
                retlw B'00000000'       ; CHARACTER $8C
                retlw B'00000000'       ; 1st half word OUT
                retlw B'00110010'
                retlw B'01001010'
                retlw B'01001010'
                retlw B'00110001'
                retlw B'00000000'
                retlw B'00000000'
                 
                retlw B'00000000'       ; CHARACTER $8D
                retlw B'00000000'       ; 2nd half word OUT
                retlw B'01011111'
                retlw B'01000100'
                retlw B'01000100'
                retlw B'10000100'
                retlw B'00000000'
                retlw B'00000000'
                 
                retlw B'00000000'       ; CHARACTER $8E
                retlw B'01100101'       ; word 0V
                retlw B'10010101'
                retlw B'10010101'
                retlw B'01100010'
                retlw B'00000000'
                retlw B'00000000'
                retlw B'00000000'
                 
BITSLO          andlw 7
                addwf PCL,F
                retlw B'10000000'
                retlw B'01000000'
                retlw B'00100000'
                retlw B'00010000'
                retlw B'00001000'
                retlw B'00000100'
                retlw B'00000010'
                retlw B'00000001'
                 
                                        ;.............
                 
GRAPHIC         movlw 34
                movwf COLUMN            ;set column length
                call SETUP
                 
DEM1            call DEMO1              ; basic circuit diagram
                call WAITSW             ; wait until switch pressed
                 
DEM2            call DEMO2              ; bit set/clear - square
                call WAITOFF            ; wait until switch released
                 
DEM3            call DEMO3              ; text highlight
                call WAITSW             ; wait until switch pressed
                 
DEM4            call DEMO4              ; cursor use
                call WAITSW             ; wait until switch pressed
                 
DEM5            call DEMO5              ; pan between pages
                call WAITOFF            ; wait until switch released
                 
DEM6            call DEMO6              ; switch between pages
                call WAITOFF            ; wait until switch released
                 
DEM7            call DEMO7              ; setting AND-OR-XOR modes (superimpose)
                call WAITSW             ; wait until switch pressed
                 
DEM8            call DEMO8              ; bird - data from EEPROM, slow travel right
                call WAITOFF            ; wait until switch released
                 
DEM9            call DEMO9              ; full text character set
                call WAITSW             ; wait until switch pressed
                 
DEM10           call DEMO10             ; full graphics character set
                call WAITSW             ; wait until switch pressed
                 
DEM11           call DEMO11             ; shifting waveform demo - horizontal
                call WAITOFF            ; wait until switch released
                 
DEM12           call DEMO12             ; shifting waveform demo - scope style
                call WAITOFF            ; wait until switch released
                 
                goto GRAPHIC            ; end of demo, restart from beginning
                 
                                        ;****** DEMO 1 CREATE & SHOW SYMBOLS AS TEXT CHARACTERS **********
                 
DEMO1           movlw B'10010100'       ; text on, graphic off, cursor & blink off
                call SENDCMD            ; send command
                 
                                        ; SETUP USER CG RAM
                movlw 120               ; 15 char x 8 byte = 120
                movwf LOOPC             ;
                call SETCG              ;
                 
CIRCUIT         clrf ADRMSB             ; SHOW SYMBOLS
                movlw 5                 ; set column
                call LINE1              ; set cell number for line stated
                movlw 1                 ; character quantity
                movwf LOOPC             ;
                clrf LOOPB              ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 1                 ; set column
                call LINE2              ; set cell number for line stated
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 1                 ; set column
                call LINE3              ; set cell number for line stated
                movlw 10                ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 3                 ; set column
                call LINE4              ; set cell number for line stated
                movlw 3                 ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 3                 ; set column
                call LINE5              ; set cell number for line stated
                movlw 1                 ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 3                 ; set column
                call LINE6              ; set cell number for line stated
                movlw 1                 ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
                clrf ADRMSB
                movlw 3                 ; set column
                call LINE7              ; set cell number for line stated
                movlw 1                 ; character quantity
                movwf LOOPC             ;
                call SHOWCG             ;
                 
WORDS                                   ; SHOW TEXT
                clrf ADRMSB
                movlw 0                 ; set column
                call LINE0              ; set cell number for line stated
                movlw 16                ; character quantity
                movwf LOOPC             ;
                clrf LOOPB              ; clear table loop counter
                call SHWTXT             ;
                 
                clrf ADRMSB
                movlw 6                 ; set column
                call LINE6              ; set cell number for line stated
                movlw 10                ; character quantity
                movwf LOOPC             ; table loop counter remains at last call val
                call SHWTXT             ;
                 
                clrf ADRMSB
                movlw 6                 ; set column
                call LINE7              ; set cell number for line stated
                movlw 8                 ; character quantity
                movwf LOOPC             ; table loop counter remains at last call val
                call SHWTXT             ;
                 
                clrf ADRMSB             ; THIS GOES INTO PAGE 2
                movlw 17                ; set column
                call LINE3              ; set cell number for line stated
                movlw 14                ; character quantity
                movwf LOOPC             ; table loop counter remains at last call val
                call SHWTXT             ;
                return 
                 
                                        ;********** DEMO 2 BIT SETTING/CLEARING DEMO ****************
                 
DEMO2           movlw B'10000000'       ; internal CG RAM mode, OR mode
                call SENDCMD            ; send command
                 
                clrf ADRMSB             ; TEXT HOME ADDRESS $00xx
                clrf ADRLSB             ; set for PAGE 1
                call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
                movlw B'10011100'       ; text & graphic on, cursor & blink off
                call SENDCMD            ; send command
                 
                                        ; ** SET SINGLE CENTRE BIT **
                movlw 12                ; set column number
                movwf ADRLSB
                movlw 23                ; set graph line
                call GLINE              ; multiply by line length to get address
                movlw B'11111000'       ; set bit 0
                call BITWRITE
                 
                movlw B'11111000'       ; bits 0-2 indicate bit affected
                movwf STORE1            ; bit 3 high set, low = clear
                 
                                        ; ** DRAW SQUARE **
SQUARE          movlw 11                ; set column number
                movwf ADRLSB
                movlw 30                ; set graph line
                call GLINE              ; multiply by line length to get address
                 
                movlw 16
                movwf LOOPC
SQ1             movf STORE1,W           ; draw up
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                movf COLUMN,W
                subwf ADRLSB,F
                btfss STATUS,C
                decf ADRMSB,F
                decfsz LOOPC,F
                goto SQ1
                 
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
SQ1A            movf COLUMN,W           ; draw right
                addlw 1
                addwf ADRLSB,F
                btfsc STATUS,C
                incf ADRMSB,F
                 
                movlw 8
                movwf LOOPC
SQ2             decf LOOPC,W
                iorwf STORE1,W
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                decfsz LOOPC,F
                goto SQ2
                 
                incf ADRLSB,F
                movlw 8
                movwf LOOPC
SQ3             decf LOOPC,W
                iorwf STORE1,W
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                decfsz LOOPC,F
                goto SQ3
                 
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
SQ3A            movlw 16                ; draw down
                movwf LOOPC
SQ4             movf STORE1,W
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                movf COLUMN,W
                addwf ADRLSB,F
                btfsc STATUS,C
                incf ADRMSB,F
                decfsz LOOPC,F
                goto SQ4
                 
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
SQ4A            movf COLUMN,W           ; draw left
                subwf ADRLSB,F
                btfss STATUS,C
                decf ADRMSB,F
                 
                clrf LOOPC
SQ5             movf LOOPC,W
                iorwf STORE1,W
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                incf LOOPC,F
                btfss LOOPC,3
                goto SQ5
                 
                decf ADRLSB,F
                clrf LOOPC
SQ6             movf LOOPC,W
                iorwf STORE1,W
                call BITWRITE
                btfss PORTA,4           ; check switch
                goto ENDDEMO2
                 
                call PAUSE2
                incf LOOPC,F
                btfss LOOPC,3
                goto SQ6
                 
                movlw B'00001000'       ; toggle between set/clear by bit 3
                addwf STORE1,W
                iorlw B'11110000'
                movwf STORE1
                 
                btfsc PORTA,4           ; check switch
                goto SQUARE
                 
ENDDEMO2        return 
                 
                                        ;************* DEMO 3 HOW TO HIGHLIGHT TEXT ****************
                 
DEMO3                                   ;  ** FILL SELECTED GRAPHIC AREA WITH SELECTED ATTRIBUTE VALUE **
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 0                 ; set column
                call LINE0              ; set cell number for line stated
                movlw 16                ; character quantity to be affected
                movwf LOOPC             ;
                movlw B'11110101'       ; attribute reverse *
                movwf ATTRIB
                call SETATTR            ;
                                        ; * TRY THESE ATTRIBUTE OPTIONS:
                                        ; movlw %00000000 ; attribute normal
                                        ; movlw %11110101 ; attribute reverse
                                        ; movlw %00001000 ; attribute blink normal
                                        ; movlw %00001101 ; attribute blink reverse
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 6                 ; set column
                call LINE6              ; set cell number for line stated
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                movlw B'00001101'       ; attribute blink reverse
                movwf ATTRIB
                call SETATTR            ;
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 6                 ; set column
                call LINE7              ; set cell number for line stated
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                movlw B'00001101'       ; attribute blink reverse
                movwf ATTRIB
                call SETATTR            ;
                 
                                        ; ** SET FOR TEXT ATTRIBUTE MODE **
                movlw B'10000100'       ; text attribute mode
                call SENDCMD            ; send command
                movlw B'10011100'       ; text & graphic on, cursor & blink off
                call SENDCMD            ; send command
                return 
                 
                                        ;*********** DEMO 4 SETTING CURSOR ************
                 
DEMO4           movlw B'10010111'       ; text on, graphic off, cursor & blink on
                call SENDCMD            ; send command
                 
                                        ; set cursor position + type
                movlw 15                ; set column
                movwf ADRLSB
                movlw 3                 ; set line
                movwf ADRMSB
                call CSRADR
                call CSRTYP             ;set type (specified in sub-routine)
                return                  ;         (from 1 to 8 lines high)
                 
                                        ;*********** DEMO 5 PANNING BETWEEN PAGES ************
                 
DEMO5                                   ; ** SHIFT PAGE 1 LEFT TO REVEAL PAGE 2
                 
                clrf ADRMSB             ; TEXT HOME ADDRESS $00xx
                movlw 1
                movwf ADRLSB            ; set for PAGE 1 col 1
                 
                movlw 16                ;
                movwf LOOPC
SL2             call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
SL2A            movlw 5                 ; short pause
                movwf LOOPB
WAIT2           btfss PORTA,4
                goto ENDDEMO5
                call PAUSIT
                decfsz LOOPB,F
                goto WAIT2
                 
                incf ADRLSB,F
                decfsz LOOPC,F
                goto SL2
                 
                movlw 17                ; ** SHIFT PAGE 2 RIGHT TO REVEAL PAGE 1
                movwf LOOPC
                movlw 16
                movwf ADRLSB            ; set for PAGE 2
SL3             call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
SL3A            movlw 5                 ; short pause
                movwf LOOPB
WAIT3           btfss PORTA,4
                goto ENDDEMO5
                call PAUSIT
                decfsz LOOPB,F
                goto WAIT3
                 
                decf ADRLSB,F
                decfsz LOOPC,F
                goto SL3
                goto DEMO5
                 
ENDDEMO5        return 
                 
                                        ;*********** DEMO 6 SWITCHING BETWEEN PAGES ************
                 
DEMO6           movlw B'10000000'       ; (OR mode, Internal CG mode)
                call SENDCMD            ; send command
                 
DEMO6A                                  ;** CHANGE PAGE **
                clrf ADRMSB             ; TEXT HOME ADDRESS $00xx
                movlw 17                ; set for PAGE 2
                movwf ADRLSB
                clrf LOOPC
SL1             call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
SL1A            movlw 5                 ; short pause
                movwf LOOPB
WAIT            btfss PORTA,4           ; check switch press
                goto ENDDEMO6
                call PAUSIT
                decfsz LOOPB,F
                goto WAIT
                 
                incf LOOPC,F
                clrf ADRLSB             ; set for PAGE 1
                btfss LOOPC,1
                goto SL1
                goto DEMO6A
                 
ENDDEMO6        return 
                 
                                        ;*********** DEMO 7 SETTING AND-OR-XOR MODES ***************
                 
DEMO7                                   ; ** FILL SELECTED GRAPHIC SCREEN AREA WITH VALUES FOR AND-OR-XOR **
                 
                                        ; first clear attribute data for text lines 0, 6 & 7 set in DEMO3
                                        ; but graphic data set in DEMO2 (SQUARE) not cleared
                 
                movlw B'10000000'       ; clear text attribute mode
                call SENDCMD            ; send command
                 
                movlw B'10011100'       ; text & graphic on, cursor & blink off
                call SENDCMD            ; send command
                 
                clrf ADRMSB             ; TEXT HOME ADDRESS $00xx
                movlw 0
                movwf ADRLSB
                call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 0                 ; set column
                call LINE0              ; set cell number for line stated
                movlw 16                ; character quantity to be affected
                movwf LOOPC             ;
                clrf ATTRIB
                call SETATTR
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 6                 ; set column
                call LINE6              ; set cell number for line stated
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                clrf ATTRIB
                call SETATTR            ;
                 
                movlw 2                 ; set graphic address ($02xx)
                movwf ADRMSB
                movlw 6                 ; set column
                call LINE7              ; set cell number for line stated
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                clrf ATTRIB
                call SETATTR            ;
                 
                                        ; ** start of AND-OR XOR mode proper **
                 
                clrf ADRMSB             ; TEXT HOME ADDRESS $00xx
                movlw 0
                movwf ADRLSB
                call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                 
                movlw 15                ;
                movwf LOOPD             ; set line start
AND2            movlw 1                 ; set column number
                movwf ADRLSB
                movf LOOPD,W            ; set graph line
                call GLINE              ; multiply by line length
                movlw 10                ; character quantity
                movwf LOOPC             ;
                movlw B'10101010'       ; fill graphic with val shown
                btfss LOOPD,0
                movlw B'01010101'       ; fill graphic with val shown
                movwf ATTRIB
                call SETATTR            ; send value
                incf LOOPD,F            ; inc line count
                movf LOOPD,W
                xorlw 33                ; has line count reached max?
                btfss STATUS,Z
                goto AND2
                 
SETAND                                  ;  ** SET AND-OR-XOR MODE ** TRY ANY OF THESE OPTIONS:
                movlw B'10000001'       ; internal CG RAM mode, XOR
                                        ;       movlw %10000000   ; internal CG RAM mode, OR
                                        ;       movlw %10000011   ; internal CG RAM mode, AND
                call SENDCMD            ; send command
                 
                                        ;  ** CHANGE DISPLAY MODE ** TRY ANY OF THESE OPTIONS:
                movlw B'10011100'       ; text & graphic on, cursor & blink off
                                        ;        movlw %10010100   ; text on, graphic off, cursor & blink off
                                        ;        movlw %10011000   ; text off, graphic on, cursor & blink off
                call SENDCMD            ; send command
                return 
                 
                                        ;******* DEMO 8 GET GRAPHICS (BIRD) FROM EEPROM, DRAW & REPEAT SHIFT RIGHT ***
                 
DEMO8           call CLRTXT
                call CLRGRAPH
                 
                movlw 16                ; change column length to 16
                movwf COLUMN
                call TEXTAREA           ; SET TEXT AREA
                call GRAPHAREA          ; SET GRAPHIC AREA
                 
                movlw B'10000000'       ; internal CG RAM mode, OR
                call SENDCMD            ; send command
                movlw B'10011100'       ; text & graphic on, cursor & blink off
                call SENDCMD            ; send command
                 
EPE             clrf ADRMSB             ; show EPE text PT1
                movlw 1                 ; set column
                movwf ADRLSB
                call LINE0              ; set line
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                movlw 16                ; position in table
                movwf LOOPB             ; set table loop counter
                call SHWTXT             ;
                 
                clrf ADRMSB             ; set and show EPE text PT2
                movlw 11                ; set column
                movwf ADRLSB
                call LINE0              ; set line
                movlw 4                 ; character quantity
                movwf LOOPC             ;
                movlw 30                ; position in table
                movwf LOOPB             ; set table loop counter
                call SHWTXT             ;
                 
                bsf STATUS,RP1          ; set PIC's Page 2 and EEPROM reading address
                clrf EEADR
                bcf STATUS,RP1
                 
                clrf LOOPD
                clrf LOOPE
                 
BIRDX           movf LOOPE,W
                movwf ADRLSB            ; set column
                movlw 20                ; set line
                call GLINE              ; multiply by line length to get address
                 
BIRD2           movlw 32                ; get & show BIRD details from EEPROM
                movwf LOOPB
BIRD2A          call PRMGET
                call ONEWRITE
                movf COLUMN,W
                addwf ADRLSB,F
                btfsc STATUS,C
                incf ADRMSB,F
                decfsz LOOPB,F
                goto BIRD2A
                incf LOOPE,F
                btfss LOOPE,4
                goto BIRDX
                 
BEAK1           bsf STATUS,RP1
                movlw 202               ; set for reading from EEPROM byte 202
                movwf EEADR
                bcf STATUS,RP1
                movlw 3                 ;
                movwf LOOPC
                 
                movlw H'14'             ; CG RAM start address $1400 + 128
                movwf ADRMSB            ; (character code $90)
                movlw 128               ; 
                movwf ADRLSB            ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                 
BK2             call PRMGET             ; get BIRD beak details from EEPROM
                call AUTOWRITE          ; auto write beak as character $90 
                incf EEADR,F            ; just 3 lines of eeprom taken as $90
                decfsz LOOPC,F          ;  is assumed to have been cleared earlier
                goto BK2
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                 
                movlw 51                ; start line for water
                movwf LOOPE
                movlw 12                ; number of lines to be filled
                movwf LOOPD
                 
WATER           movlw 0                 ; draw "WATER"
                movwf ADRLSB            ; set column
                movf LOOPE,W            ; set line
                call GLINE              ; multiply by line length
                movlw 16                ; character quantity
                movwf LOOPC
                movlw B'10101010'       ; "WATER" pattern - try changing this value
                movwf ATTRIB
                call SETATTR
                incf LOOPE,F
                decfsz LOOPD,F
                goto WATER
                 
                movlw 28
                movwf LOOPE
                movlw JOIN00            ; clear JOIN variables
                movwf FSR
CLRJOIN         clrf INDF
                incf FSR,F
                decfsz LOOPE,F
                goto CLRJOIN
                movlw 6
                movwf QCKCOL            ; set quack bill column
                movlw 1                 ; loop period before next quack
                movwf COUNT
                 
BIRDZ           movlw 23                ; set start line for shift right of display
                movwf LOOPE
                clrf ADRLSB             ; set column
                movf LOOPE,W            ; set line
                call GLINE              ; multiply by line length
                call SCREENADR          ; set screen write address
                movlw JOIN00            ; set join variable for right-hand line bit
                movwf FSR
                 
BIRDY           movlw 16                ;
                movwf LOOPD             ; set loop val (number of columns to be shifted)
                 
BIRDY2          call DATAREAD           ; read screen, returns with val held in RDBYTE
                rlf INDF,F              ; rotate STORE into CARRY
                rrf RDBYTE,F            ; rotate RDBYTE and bring in CARRY bit
                rrf INDF,F              ; shift CARRY into STORE
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                call CHECK3             ; read status for DA0/DA1 = 3
                movf RDBYTE,W           ; re-store RDBYTE on screen
                call OUTDATA            ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                decfsz LOOPD,F
                goto BIRDY2             ; repeat until done
                 
                btfss PORTA,4           ; check switch
                return 
                 
                incf FSR,F              ; inc JOIN store address
                incf LOOPE,F            ; inc line number
                movf LOOPE,W
                xorlw 51
                btfss STATUS,Z          ; has line limit been reached?
                goto BIRDY              ; no, so repeat for next line
                 
                decf COUNT,F            ; dec counter
                btfss STATUS,Z          ; is it zero?
                goto BIRDZ              ; no, so start again
                 
QUACK            
                clrf ADRMSB             ; show beak
                movf QCKCOL,W           ; set column
                call LINE4              ; set line
                movlw H'90'             ; beak symbol
                call ONEWRITE
                 
                clrf ADRMSB             ; show QUACK text
                movlw 5                 ; set column
                movwf ADRLSB
                call LINE1              ; set line
                movlw 5                 ; character quantity
                movwf LOOPC             ;
                movlw 48
                movwf LOOPB             ; set table loop counter
                call SHWTXT             ;
                 
                movlw 3                 ; short pause
                movwf LOOPB
QK2             call PAUSIT
                decfsz LOOPB,F
                goto QK2
                 
                clrf ADRMSB             ; clear QUACK text
                movlw 5                 ; set column
                movwf ADRLSB
                call LINE1              ; set line
                movlw 5                 ; character quantity
                movwf LOOPC
                movlw 0                 ; clear QUACK
                movwf ATTRIB
                call SETATTR
                 
                clrf ADRMSB             ; clear QUACK bill
                movf QCKCOL,W           ; set column
                movwf ADRLSB
                call LINE4              ; set line
                movlw 0
                call ONEWRITE
                incf QCKCOL,F
                bcf QCKCOL,4
                 
                movlw 8                 ; set QUACK period loop count
                movwf COUNT
                movf QCKCOL,W
                btfsc STATUS,Z
                incf COUNT,F
                goto BIRDZ
                 
                                        ;******* DEMO 9 SHOW FULL ALPHANUMERIC TEXT SET ***
                 
DEMO9                                   ;  ** WRITE FULL ASCII TEXT **
                movlw B'10010100'       ; text on, graphic off, cursor & blink off
                call SENDCMD            ; send command
                 
                clrf ADRMSB             ;
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                clrf LOOPB
DM9             movf LOOPB,W            ;
                call AUTOWRITE          ; auto write and increment
                incf LOOPB,F            ;
                btfss LOOPB,7
                goto DM9                ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;******* DEMO 10 SHOW CHARACTER GEN SYMBOL TEXT SET ***
                 
DEMO10                                  ;  ** FIRST COPY EEPROM INTO CG RAM **
                 
                bsf STATUS,RP1          ; set for PIC its Page 2 for EEPROM reading
                clrf EEADR
                bcf STATUS,RP1
                 
                movlw H'14'             ; CG RAM start address $1400 + 136
                movwf ADRMSB            ;
                movlw 136
                movwf ADRLSB            ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; SET DATA AUTO WRITE ON
                call SENDCMD            ; send command
                clrf LOOPB              ;
                movlw 224
                movwf LOOPC
                 
SETEG2          movf LOOPB,W            ; WRITE TO EXTERNAL RAM
                call PRMGET
                call AUTOWRITE          ; auto write and increment
                incf LOOPB,F            ; 
                decfsz LOOPC,F          ; LOOPC val specified by calling routine
                goto SETEG2             ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                 
                                        ;  ** WRITE FULL NON-ASCII TEXT AS HELD IN CG RAM **
                clrf ADRMSB             ;
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                movlw 128               ; first CG RAM character  $80 = 128
                movwf LOOPB
DM10            movf LOOPB,W            ;
                call AUTOWRITE          ; auto write and increment
                incfsz LOOPB,F          ;
                goto DM10               ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;******** DEMO 11 CREATE MOVING WAVEFORM - HORIZONTAL *************
                 
DEMO11          call CLRTXT
                movlw B'10011100'       ; text on, graphic on, cursor & blink off
                call SENDCMD            ; send command
                 
                clrf ADRMSB             ; show EPE text PT1
                movlw 1                 ; set column
                movwf ADRLSB
                call LINE0              ; set line
                movlw 9                 ; character quantity
                movwf LOOPC             ;
                movlw 16                ; position in table
                movwf LOOPB             ; set table loop counter
                call SHWTXT             ;
                 
                clrf ADRMSB             ; set and show EPE text PT2
                movlw 11                ; set column
                movwf ADRLSB
                call LINE0              ; set line
                movlw 4                 ; character quantity
                movwf LOOPC             ;
                movlw 30                ; position in table
                movwf LOOPB             ; set table loop counter
                call SHWTXT             ;
                 
                movlw 16                ; clear temp storage memory
                movwf LOOPD
                movlw JOIN00
                movwf FSR
CLRMEM          clrf INDF
                incf FSR,F
                decfsz LOOPD,F
                goto CLRMEM
                 
                clrf COUNT              ; volts simulator counter
                clrf PEAKLO
                 
WAVE0           clrf LOOPE              ; set start line
WAVE1           clrf ADRMSB
                clrf ADRLSB
                 
                movf COUNT,W            ; copy loop val into PEAKHI
                movwf PEAKHI
                 
                subwf PEAKLO,W          ; is PEAKHI > PEAKLO ?
                btfss STATUS,C          ; is there a borrow?
                goto WAVE2              ; yes
                 
                movf PEAKLO,W           ; no, so swap lo & hi
                movwf PEAKHI
                movf COUNT,W
                movwf PEAKLO
                 
WAVE2           movf PEAKLO,W           ; get LO remainder less than 8
                call BITSLO
                movwf LOBIT
                 
                rlf PEAKLO,W            ; get LO integer (i.e. divide by 8)
                movwf LOOPLO
                swapf LOOPLO,W
                andlw 15
                movwf LOOPLO
                 
                movf LOOPLO,W           ; set address for 1st temp store memory
                addlw JOIN00
                movwf FSR
                 
                bcf STATUS,C
                movf PEAKLO,W
                movwf LOOPD
                 
WAVE3           movf LOOPD,W
                xorwf PEAKLO,W
                btfsc STATUS,Z
                goto WAVE4
                movf LOBIT,W
                iorwf INDF,F
                incf LOOPD,F
                btfsc LOOPD,7
                goto WAVE5
                bcf STATUS,C
                rrf LOBIT,F
                btfss STATUS,C
                goto WAVE3
                incf FSR,F
                bsf LOBIT,7
                bcf STATUS,C
                goto WAVE3
                 
WAVE4           movf LOOPD,W
                xorwf PEAKHI,W
                btfsc STATUS,Z
                goto WAVE5
                movf LOBIT,W
                iorwf INDF,F
                incf LOOPD,F
                btfsc LOOPD,7
                goto WAVE5
                bcf STATUS,C
                rrf LOBIT,F
                btfss STATUS,C
                goto WAVE4
                incf FSR,F
                bsf LOBIT,7
                bcf STATUS,C
                goto WAVE4
                 
WAVE5           movlw JOIN00
                movwf FSR
                clrf LOOPD
                clrf ADRLSB             ; set column
                movf LOOPE,W            ; set line
                call GLINE              ; multiply by line length
                call SCREENADR          ; set screen write address
                 
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                 
WAVE6           movf INDF,W             ; send data to LCD
                call OUTDATA
                clrf INDF
                incf FSR,F
                incf LOOPD,F
                btfss LOOPD,4
                goto WAVE6
                movf COUNT,W
                movwf PEAKLO
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                 
WAVE7           movlw 4
                addwf COUNT,F           ; add to volts loop
                bcf COUNT,7
                btfss PORTA,4           ; is switch on?
                return                  ; yes
                incf LOOPE,F            ; no, inc line number
                movf LOOPE,W
                xorlw 64
                btfss STATUS,Z          ; has line limit been reached?
                goto WAVE1              ; no, so repeat for next line
                decf COUNT,F            ; introduce a displacement to uniform count
                goto WAVE0              ; yes so start again
                 
                                        ;******** DEMO 12 CREATE MOVING WAVEFORM - SCOPE STYLE *************
                 
DEMO12          movlw B'10011100'       ; text on, graphic on, cursor & blink off
                call SENDCMD            ; send command
                clrf COUNT              ; volts simulator counter
                clrf PEAKLO
                clrf LOOPD
                 
SCOPE0          movlw B'10000000'       ; indicates which bit of column is affected
                movwf LOBIT
                 
SCOPE1          movf COUNT,W            ; copy loop val into PEAKHI
                movwf PEAKHI
                subwf PEAKLO,W          ; is PEAKHI > PEAKLO ? (subtract hi from lo)
                btfss STATUS,C          ; is there a borrow?
                goto SCOPE2             ; yes
                 
                movf PEAKLO,W           ; no, so swap lo & hi
                movwf PEAKHI
                movf COUNT,W
                movwf PEAKLO
                 
SCOPE2          movlw JOIN00            ; set address for 1st affected temp store memory
                addwf PEAKLO,W
                movwf FSR
                movf PEAKLO,W           ; set loop to val of PEAKLO
                movwf LOOPE
                movf LOBIT,W
                iorwf INDF,F            ; set new bit
                 
SCOPE3          movf LOOPE,W            ; is loop = peakhi?
                xorwf PEAKHI,W
                btfsc STATUS,Z
                goto SCOPE4             ; yes
                movf LOBIT,W            ; no
                iorwf INDF,F            ; set new bit
                incf LOOPE,F
                btfsc LOOPE,6
                goto SCOPE4
                incf FSR,F
                goto SCOPE3
                 
SCOPE4          movf COUNT,W
                movwf PEAKLO
                movlw 2
                addwf COUNT,F           ; inc wavform counter
                bcf COUNT,6             ; limit to 63 max
                bcf STATUS,C
                rrf LOBIT,F             ; shift right bitting setting val
                btfss STATUS,C          ; is CARRY set? (stating all 8 bits of col done)
                goto SCOPE1             ; no
                 
                movlw JOIN00            ; send 8-bit column to screen
                movwf FSR
                movlw 64
                movwf LOOPE             ; set loop val (number of columns)
                movlw 2                 ; set graphic base address ($02xx)
                movwf ADRMSB
                movf LOOPD,W            ; set column
                movwf ADRLSB
                 
SCOPE5          call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                call CHECK3             ; read status for DA0/DA1 = 3
                movf INDF,W             ; get val from STORE
                call OUTDATA            ;
                clrf INDF
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                incf FSR,F
                decf LOOPE,F
                btfsc STATUS,Z
                goto SCOPE6
                movf COLUMN,W           ; set for next line
                addwf ADRLSB,F
                btfsc STATUS,0          ; add CARRY (if any) to MSB
                incf ADRMSB,F
                goto SCOPE5             ; repeat until done
                 
SCOPE6          incf LOOPD,F            ; inc to next column
                btfss LOOPD,4
                goto SCOPE0
                 
                clrf LOOPD              ; start again at screen left
                movlw 3                 ; add displacement factor to waveform loop
                subwf COUNT,W
                 
                andlw B'00111111'
                movwf COUNT
                btfsc PORTA,4           ; is switch on?
                goto SCOPE0             ; no, so repeat
                return                  ; yes
                 
                                        ;********** END DEMOS - START OF SUB-ROUTINES ***************
                 
BITWRITE                                ; ** WRITE SINGLE SINGLE BIT DATA ROUTINE **
                movwf BITVAL
                call SCREENADR          ; set screen write address
                movf BITVAL,W
                call SENDCMD            ; send command
                return                  ;
                 
                                        ;.........
                 
ONEWRITE                                ;  ** WRITE SINGLE BYTE **
                movwf ATTRIB            ; temp store val brought in on W
                call SCREENADR          ; set screen write address - vals preset at call
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                call CHECK3             ; read status for DA0/DA1 = 3
                movf ATTRIB,W
                call OUTDATA            ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                                        ;............
                 
AUTOWRITE                               ; ** AUTO WRITE ROUTINE **
                movwf TEMPA             ; temp store value brought in on W
                call CHECK8             ; read status for DA3 = 8
                movf TEMPA,W            ; WRITE DATA
                call OUTDATA            ;
                return                  ;
                 
                                        ;..............
                 
CMDADR                                  ; ** SET ADDRESS FOR COMMAND SENDING **
                call CHECK3             ; read status for DA0/DA1 = 3
                movf ADRLSB,W           ; WRITE DATA D1
                call OUTDATA            ;
                call CHECK3             ; read status for DA0/DA1 = 3
                movf ADRMSB,W           ; WRITE DATA D2
                call OUTDATA            ;
                return                  ;
                 
                                        ;.........
                 
SCREENADR                               ; ** SET ADDRESS FOR WRITE/READ TO/FROM SCREEN
                call CHECK3             ; read status for DA0/DA1 = 3
                movf ADRLSB,W           ; WRITE ADDRESS LSB
                call OUTDATA            ;
                call CHECK3             ; read status for DA0/DA1 = 3
                movf ADRMSB,W           ; WRITE ADDRESS MSB
                call OUTDATA            ;
                movlw ADPSET            ; SET ADDRESS POINTER
                call SENDCMD            ; send command
                return                  ;
                 
                                        ;.............
                 
TEXTHOME                                ; ** SET TEXT HOME ADDRESS **
                clrf ADRMSB             ; TEXT HOME ADDRESS $0000
                clrf ADRLSB             ;
                call CMDADR             ; send command address
                movlw TXHOME            ;
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
GRAPHHOME                               ;  ** SET GRAPHIC HOME ADDRESS **
                movlw H'02'             ; GRAPHIC HOME ADDRESS $0200
                movwf ADRMSB
                clrf ADRLSB
                call CMDADR             ; send command address
                movlw GRHOME            ;
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
TEXTAREA                                ; ** SET TEXT AREA **
                clrf ADRMSB             ;
                movf COLUMN,W           ; columns length
                movwf ADRLSB            ;
                call CMDADR             ; send command address
                movlw TXAREA            ; text area command
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
GRAPHAREA                               ; ** SET GRAPHIC AREA **
                clrf ADRMSB             ;
                movf COLUMN,W           ; columns length
                movwf ADRLSB            ;
                call CMDADR             ; send command address
                movlw GRAREA            ; graphic area command
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
CSRADR                                  ;  ** SET CURSOR POSITION **
                call CMDADR             ; send command address
                movlw CSRPOS            ; cursor position command
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
CSRTYP                                  ;  ** SET CURSOR TYPE **
                movlw B'10100111'       ; 8-line
                call SENDCMD            ; send command
                return                  ; OPTIONS:
                                        ; %10100000   ; 1-line
                                        ; %10100001   ; 2-line
                                        ; %10100010   ; 3-line
                                        ; %10100011   ; 4-line
                                        ; %10100100   ; 5-line
                                        ; %10100101   ; 6-line
                                        ; %10100110   ; 7-line
                                        ; %10100111   ; 8-line
                                        ;...........
                 
SETMODE                                 ;  ** SET MODE - MANY OPTIONS, see EPE text **
                movlw B'10000000'       ; (OR mode, Internal CG mode)
                                        ;       movlw %10000000   ; External CG RAM mode, OR
                                        ;       movlw %10000011   ; External CG RAM mode, AND
                                        ;       movlw %10000001   ; External CG RAM mode, XOR
                                        ;       movlw %10000100   ; text attribute mode
                call SENDCMD            ; send command
                return 
                                        ; %1000x000   ; OR mode
                                        ; %1000x001   ; XOR mode
                                        ; %1000x011   ; AND mode
                                        ; %1000x100   ; Text Attribute mode
                                        ; %10000xxx   ; Internal CG ROM mode
                                        ; %10001xxx   ; External CG RAM mode
                 
                                        ;...........
                 
SETOFFSET                               ; ** SET OFFSET REGISTER **
                                        ; setting OFFSET address at 2 selects
                                        ; CG RAM START ADDRESS = $1400 where
                                        ; $80 is character number of 1st graphic byte
                                        ; values below that call ASCII text characters
                clrf ADRMSB             ;
                movlw 2                 ;
                movwf ADRLSB            ;
                call CMDADR             ; send command address
                movlw OFFSET            ;
                call SENDCMD            ; send command
                return 
                 
                                        ;...........
                 
SETDISPLAY                              ;  ** DISPLAY MODE **  SOME OPTIONS:
                movlw B'10010100'       ; text on, graphic off, cursor & blink off
                                        ;        movlw %10011100   ; text on, graphic on, cursor & blink off
                                        ;        movlw %10011000   ; text off, graphic on, cursor & blink off
                call SENDCMD            ; send command
                return                  ; OTHER OPTIONS:
                                        ; %10010000 display off
                                        ; %1001xx10 cursor on, blink off
                                        ; %1001xx11 cursor on, blink on
                                        ; %100101xx text on, graphic off
                                        ; %100110xx text off, graphic on
                                        ; %100111xx text on, graphic on
                 
                                        ;...........
                 
CLRTXT                                  ;  ** CLEAR TEXT AREA ($0000) **
                clrf ADRMSB             ; clear all text screen lines, length as set
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                movlw 8                 ; number of lines
                movwf LOOPC
CLR2            movf COLUMN,W           ; column length
                movwf LOOPB             ;
CLR3            movlw 0                 ; write 0
                call AUTOWRITE          ; auto write and increment
                decfsz LOOPB,F          ;
                goto CLR3               ;
                decfsz LOOPC,F          ;
                goto CLR2               ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;............
                 
CLRGRAPH                                ; ** CLEAR GRAPH AREA ($0200) **
                movlw H'02'
                movwf ADRMSB            ;
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                movlw 64                ; number of lines
                movwf LOOPC
CLRG2           movf COLUMN,W           ; column length
                movwf LOOPB             ;
CLRG3           movlw 0                 ; write 0
                call AUTOWRITE          ; auto write and increment
                decfsz LOOPB,F          ;
                goto CLRG3              ;
                decfsz LOOPC,F          ;
                goto CLRG2              ;
                movlw AWROFF            ; AUTO RESET OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;..............
                 
CLRCG                                   ; ** CLEAR CG RAM AREA ($1400) **
                movlw H'14'
                movwf ADRMSB            ;
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
                movlw 64                ; number of lines
                movwf LOOPC
CLRCG2          movf COLUMN,W           ; column length
                movwf LOOPB             ;
CLRCG3          movlw 0                 ; write 0
                call AUTOWRITE          ; auto write and increment
                decfsz LOOPB,F          ;
                goto CLRCG3             ;
                decfsz LOOPC,F          ;
                goto CLRCG2             ;
                movlw AWROFF            ; AUTO RESET OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;............
                 
SETCG                                   ;  ** SETUP USER CG RAM **
                movlw H'14'             ; CG RAM start address 1400H
                movwf ADRMSB            ;
                clrf ADRLSB             ;
                call SCREENADR          ; set screen write address
                movlw AWRON             ; SET DATA AUTO WRITE ON
                call SENDCMD            ; send command
                clrf LOOPB              ;
                 
SETCG2          movf LOOPB,W            ; WRITE TO EXTERNAL RAM
                call CGTABLE            ; get table data
                call AUTOWRITE          ; auto write and increment
                incf LOOPB,F            ; 
                decfsz LOOPC,F          ; LOOPC val specified by calling routine
                goto SETCG2             ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;..............
                 
SHWTXT                                  ;  ** SHOW TEXT HELD IN TABLE **
                call SCREENADR          ; set screen write address - vals preset at call
                movlw AWRON             ; SET AUTO WRITE ON
                call SENDCMD            ; send command
SHTXT1          movf LOOPB,W            ; LOOPB val specified by calling routine
                call TABLE1             ; get table data and convert to graphic LCD val
                addlw 224               ; +224 is same as -32 for conversion from ASCII
                call AUTOWRITE          ; auto write and increment
                incf LOOPB,F            ;
                decfsz LOOPC,F          ; LOOPC val specified by calling routine
                goto SHTXT1             ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;..............
                 
SETATTR                                 ;  ** SEND ATTRIBUTE & OTHER DATA TO SCREEN AS 1 CHARACTER, LOOPED
                call SCREENADR          ; set screen write address - vals preset at call
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
SETAT           movf ATTRIB,W           ; val to be sent preset at call
                call AUTOWRITE          ; auto write and increment
                decfsz LOOPC,F          ; LOOPC val specified by calling routine
                goto SETAT              ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;............
                 
SHOWCG                                  ;  ** SHOW USER CG RAM IN ORDER HELD BY TABLE **
                call SCREENADR          ; set screen write address - vals preset at call
                movlw AWRON             ; AUTO WRITE ON
                call SENDCMD            ; send command
SHWCG2          movf LOOPB,W            ;
                call AMPLIFIER          ; get table data
                call AUTOWRITE          ; auto write and increment
                incf LOOPB,F            ;
                decfsz LOOPC,F          ; LOOPC val specified by calling routine
                goto SHWCG2             ;
                movlw AWROFF            ; AUTO WRITE OFF
                call SENDCMD            ; send command
                return 
                 
                                        ;.........
                 
CHECK3          PAGE1                   ; STATUS CHECK for DA0/DA1 = 3
                movlw 255               ;
                movwf TRISD             ; set PORTD as inputs
                PAGE0                   ; RST  CD  CE  RD  WR  
                movlw B'00011001'       ;  1   1   0   0   1  
                movwf PORTC             ; set CE, RD low
                nop 
CK3             btfss PORTD,0           ; PORTD bit 0 set?
                goto CK3                ; no
CK3A            btfss PORTD,1           ; PORTD bit 1 set?
                goto CK3A               ; no  RST  CD  CE  RD  WR  
                movlw B'00011111'       ;      1   1   1   1   1
                movwf PORTC             ; set controls
                nop 
                PAGE1                   ;
                clrf TRISD              ; set PORTD as outputs
                PAGE0                   ;
                return 
                 
                                        ;............
                 
CHECK6          PAGE1                   ; STATUS CHECK for DA6 low
                bsf TRISD,6             ; set PORTD bit as input
                PAGE0                   ; RST  CD  CE  RD  WR
                movlw B'00011001'       ;  1   1   0   0   1
                movwf PORTC             ; set CE, RD low
                nop 
CK6             btfsc PORTD,6           ; is PORTD bit 6 low?
                goto CK6                ; no RST  CD  CE  RD  WR
                movlw B'00011111'       ;     1   1   1   1   1
                movwf PORTC             ; set controls
                nop 
                PAGE1                   ;
                bcf TRISD,6             ; set PORTD bit 6 as output
                PAGE0                   ;
                return 
                 
                                        ;............
                 
CHECK8          PAGE1                   ; STATUS CHECK for DA3 = 8
                bsf PORTD,3             ; set PORTD bit 3 as input
                PAGE0                   ; RST  CD  CE  RD  WR
                movlw B'00011001'       ;  1   1   0   0   1
                movwf PORTC             ; set CE, RD low
                nop 
CK8             btfss PORTD,3           ; is PORTD,3 high?
                goto CK8                ; no  RST  CD  CE  RD  WR
                movlw B'00011111'       ;      1   1   1   1   1
                movwf PORTC             ; set controls
                nop 
                PAGE1                   ;
                bcf TRISD,3             ; set PORTD bit 3 as output
                PAGE0                   ;
                return 
                 
                                        ;........
                 
OUTDATA                                 ; ** SEND DATA ROUTINE **
                movwf TEMPA             ; temp store val brought in on W
                                        ; RST  CD  CE  RD  WR
                movlw B'00010111'       ;  1   0   1   1   1
                movwf PORTC             ; set CD low
                movf TEMPA,W            ; get stored data
                movwf PORTD             ; send data
                nop                     ; RST  CD  CE  RD  WR
                movlw B'00010010'       ;  1   0   0   1   0
                movwf PORTC             ; set CD, CE, WR low
                nop                     ; RST  CD  CE  RD  WR
                movlw B'00010111'       ;  1   0   1   1   1
                movwf PORTC             ; set CE, WR high
                nop                     ; RST  CD  CE  RD  WR
                movlw B'00011111'       ;  1   1   1   1   1
                movwf PORTC             ; set CD high
                return 
                 
                                        ;..........
                 
SENDCMD                                 ;  ** COMMAND WRITE ROUTINE **
                movwf TEMPA             ; temp store val brought in on W
                call CHECK3             ; read status for DA0/DA1 = 3
                movf TEMPA,W            ; WRITE COMMAND
                movwf PORTD             ; send stored data
                nop                     ; RST  CD  CE  RD  WR
                movlw B'00011010'       ;  1   1   0   1   0
                movwf PORTC             ; set CE, WR low
                nop                     ; RST  CD  CE  RD  WR
                movlw B'00011111'       ;  1   1   1   1   1
                movwf PORTC             ; set all high
                return 
                 
                                        ;.............
                 
DATAREAD                                ;  ** DATA READ ROUTINE **
                movlw PEEK              ; screen peek command
                call SENDCMD            ; send command
                PAGE1                   ;
                movlw 255               ;
                movwf TRISD             ; set PORTD as inputs
                PAGE0                   ; RST  CD  CE  RD  WR
                movlw B'00011001'       ;  1   1   0   0   1
                movwf PORTC             ; set CE, RD low
                nop 
                 
DR1             btfsc PORTD,6           ; is PORTD STATUS bit 6 low?
                goto DR1                ; no
DR2             btfss PORTD,0           ; is PORTD STATUS bit 0 high?
                goto DR2                ; no
DR3             btfss PORTD,1           ; is PORTD STATUS bit 1 high?
                goto DR3                ; no
                bcf PORTC,3             ; set CD low
                nop 
                movf PORTD,W            ; read data value
                movwf RDBYTE            ; store read value
                 
                                        ; RST  CD  CE  RD  WR  
                movlw B'00011111'       ;  1   1   1   1   1
                movwf PORTC             ; set controls
                PAGE1                   ;
                clrf TRISD              ; set PORTD as outputs
                PAGE0                   ;
                return 
                 
                                        ;...........
                 
LINE7           addwf COLUMN,W          ; sets line addresses for text screen
                btfsc STATUS,C
                incf ADRMSB,F
LINE6           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE5           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE4           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE3           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE2           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE1           addwf COLUMN,W
                btfsc STATUS,C
                incf ADRMSB,F
LINE0           movwf ADRLSB            ; COLUMN sets number of cells per line
                return                  ; ADRMSB is set/cleared before routine called
                 
                                        ;..............
                 
GLINE                                   ;** GET GRAPHIC LINE ADDRESS **
                movwf LOOPB             ; store line val
                movlw 2                 ; set graphic base address ($02xx)
                movwf ADRMSB
                movf LOOPB,W            ; line val = 0?
                btfsc STATUS,Z
                return                  ; yes
GLIN2           movf COLUMN,W           ; no, multiply line length by line val
                addwf ADRLSB,F
                movlw 1
                andwf STATUS,W          ; extract and add CARRY (if any) to MSB
                addwf ADRMSB,F
                decfsz LOOPB,F
                goto GLIN2
                return 
                 
                                        ;............
                 
                                        ;READ DATA FROM EEPROM ROUTINE modified for PIC16F87x devices
                                        ; according to data sheet DS30292A page 43
                                        ; Routine entered with eeprom byte address preset
                 
PRMGET          bsf STATUS,RP1          ; set for Page 2
                bsf STATUS,RP0          ; set for Page 3
                bcf EECON1,EEPGD        ; point to data memory
                bsf EECON1,RD           ; enable read flag
                bcf STATUS,RP0          ; set for Page 2 
                movf EEDATA,W           ; read eeprom data into W
                incf EEADR,F            ; inc address
                bcf STATUS,RP1          ; set for Page 0
                return 
                 
                                        ;.........
                 
WAITSW          btfsc PORTA,4           ; wait for switch press
                goto WAITSW
                call PAUSIT             ; allow for switch bounce, then wait switch release
                 
WAITOFF                                 ; wait for switch release
WT2             btfss PORTA,4
                goto WT2
                call PAUSIT             ; allow for switch bounce
                return 
                 
                                        ;................
                 
PAUSIT          movlw 5                 ; pause routine, 1/5th sec
                movwf CLKCNT
                clrf INTCON
PAUSE           btfss INTCON,2
                goto PAUSE
                bcf INTCON,2
                decfsz CLKCNT,F
                goto PAUSE
                return 
                 
                                        ;................
                 
PAUSE2          movlw 1                 ; pause routine, 1/25th sec
                movwf CLKCNT
                clrf INTCON
PAUS2           btfss INTCON,2
                goto PAUSE
                bcf INTCON,2
                decfsz CLKCNT,F
                goto PAUS2
                return 
                 
                                        ;..............
                 
SETUP                                   ; RST  CD  CE  RD  WR  GENERAL SETUP
                movlw B'00011111'       ;  1   1   1   1   1
                movwf PORTC             ; set controls high (off)
                call TEXTHOME           ; SET TEXT HOME ADDRESS
                call GRAPHHOME          ; SET GRAPHIC HOME ADDRESS
                call TEXTAREA           ; SET TEXT AREA
                call GRAPHAREA          ; SET GRAPHIC AREA
                call SETMODE            ; SET MODE (INT/EXT/AND-OR-XOR etc)
                call SETOFFSET          ; SET OFFSET (see EPE text)
                call SETDISPLAY         ; DISPLAY MODE (text, graph on/off etc)
                call CLRTXT             ; WRITE TEXT BLANK CODE $0000
                call CLRGRAPH           ; WRITE GRAPH BLANK CODE $0200
                call CLRCG              ; WRITE CGRAM BLANK CODE $1400
                return 
                 
                                        ;..............
                 
                end